import { getSecond, uuid } from '../../utils/common'
import { _sendVerificationCode , _checkVerificationCode } from '../../utils/sendCode'
import { VerificationCode , Account , Token , AccountDetail  } from '../../models/'
import { CODE , SEND_TIME , TOKEN_TIME , VERIFICATION_CODE_TYPE , UID_KEY } from '../../config/config'
import { _getAccount , _bindPhone } from '../../utils/account' 
/**
 * @api {post} /account/sendVerificationCode 发送验证码
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName sendVerificationCode
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/sendVerificationCode'

 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  type                  验证码类型 1.注册验证码 2.手机登陆验证码 3.找回密码验证码 4.绑定手机号验证码 
 
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/sendVerificationCode
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function sendVerificationCode(ctx) {
    const phone = ctx.request.body.phone
    const type  = ctx.request.body.type
	const verificationCode = await VerificationCode.findOne({
		where: {
			phone,type,status:1
		}
	})
	if(verificationCode) {
		const ctime = Number(verificationCode.ctime)
		if(ctime + SEND_TIME > getSecond()) { //每分钟最多一次
			verificationCode.status = 2
			await verificationCode.save()
			ctx.body = CODE.ERROR.ERROR_SEND_CODE_TIME
			return
		}
	}
	const body  = await _sendVerificationCode(phone,type)
	if(body.code == 0) {
		ctx.body = CODE.success()
	} else {
		ctx.body = CODE.ERROR.ERROR_SEND_VERIFICATION_CODE
	}

}

/**
 * @api {post} /account/findPassword 找回密码
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName findPassword
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/findPassword'

 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  code                  验证码
 * @apiParam {String}  password              新密码 
 
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/findPassword
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function findPassword(ctx,next) {  
	const phone 	  = ctx.request.body.phone
	const password    = ctx.request.body.password
	const code  	  = ctx.request.body.code
	const type  	  = VERIFICATION_CODE_TYPE.FINDPASSWORD

	const flag        = await _checkVerificationCode(phone,type,code)
	if(flag) {
		const account = await Account.findOne({where : {phone,status:1}})
		if(account) {
			account.password = password
			await account.save()
			ctx.body         = CODE.success()
			return 
		}
		ctx.body      = CODE.ERROR.ERROR_ACCOUNT_NOT_FOUND
		return
	}
	ctx.body          = CODE.ERROR.ERROR_CODE_NOT_CHECK
}

/**
 * @api {post} /account/register 注册
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName register
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/register'

 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  code                  验证码
 * @apiParam {String}  password              密码 
 
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/register
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function register(ctx,next) {  
	const phone 	  = ctx.request.body.phone
	const password    = ctx.request.body.password
	const code  	  = ctx.request.body.code
	const type  	  = VERIFICATION_CODE_TYPE.REGISTER
	const key  	      = UID_KEY.phone
	const flag        = await _checkVerificationCode(phone,type,code)
	if(flag) {
		const account = await Account.findOne({where : {phone,status:1}})
		if(account) {
			ctx.body  = CODE.ERROR.ERROR_ACCOUNT_ALREADY
			return 
		}
		await createAccount(ctx,{key,phone,password})
		return
	}
	ctx.body          = CODE.ERROR.ERROR_CODE_NOT_CHECK
}

/**
 * @api {post} /account/loginByCode 手机验证码登录
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName loginByCode
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/loginByCode'

 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  code                  验证码
 *
 *
 * @apiSuccess {Object}   account              用户信息
 * 
 * @apiSuccess {String}   token                用户token
 * @apiSuccess {String}   phone                用户手机
 * @apiSuccess {String}   icon                 用户头像
 * @apiSuccess {String}   nickname             用户昵称
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/loginByCode
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function loginByCode(ctx,next) {  
	const phone 	  = ctx.request.body.phone
	const code  	  = ctx.request.body.code
	const type  	  = VERIFICATION_CODE_TYPE.LOGIN
	const key  	      = UID_KEY.phone
	const flag        = await _checkVerificationCode(phone,type,code)
	if(flag) {
		ctx.body      = {uid:account.uid,key:UID_KEY.phone}
		if(next) {
			return next()
		}
		await createAccount(ctx,{key,phone,password})
		return
	}
	ctx.body          = CODE.ERROR.ERROR_CODE_NOT_CHECK
}

/**
 * @api {post} /account/loginByQQ QQ登录
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName loginByQQ
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/loginByQQ'

 * @apiParam {String}  qq_key                 qq登录key 
 *
 * @apiSuccess {Object}   account              用户信息
 * 
 * @apiSuccess {String}   token                用户token
 * @apiSuccess {String}   phone                用户手机
 * @apiSuccess {String}   icon                 用户头像
 * @apiSuccess {String}   nickname             用户昵称
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/loginByCode
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function loginByQQ(ctx,next) {  
	const qq_key 	  = ctx.request.body.qq_key
	const key  	      = UID_KEY.qq
	let account   = await Account.findOne({ where : {qq_key,status:1}})
	if(account) {
		ctx.body      = {uid:account.uid,key:UID_KEY.qq}
		if(next) {
			return next()
		} 
	}
	await createAccount(ctx,{key,qq_key})
}

/**
 * @api {post} /account/loginByWechat 微信登录
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName loginByWechat
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/loginByWechat'

 * @apiParam {String}  wechat_key              微信登录key 
 *
 * @apiSuccess {Object}   account              用户信息
 * 
 * @apiSuccess {String}   token                用户token
 * @apiSuccess {String}   phone                用户手机
 * @apiSuccess {String}   icon                 用户头像
 * @apiSuccess {String}   nickname             用户昵称
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/loginByWechat
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 */
export async function loginByWechat(ctx,next) {  
	const wechat_key  = ctx.request.body.wechat_key
	const key  	      = UID_KEY.wechat
	let account       = await Account.findOne({ where : {wechat_key,status:1}})
	if(account) {
		ctx.body      = {uid:account.uid,key:UID_KEY.wechat}
		if(next) {
			return next()
		}
		return 
	}
	await createAccount(ctx,{key,wechat_key})
}


/**
 * @api {post} /account/bindPhone 绑定手机号码
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName bindPhone
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/bindPhone'
 * @apiParam {String}  token                 微信登录key 
 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  code                  验证码
 *
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/bindPhone
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 * 
 */
export async function bindPhone(ctx,next) {  
	const token 	  = ctx.body.token
	const uid 	      = token.phone_uid || token.wechat_uid || token.qq_uid
	
	const phone 	  = ctx.request.body.phone
	const code  	  = ctx.request.body.code
	const type  	  = VERIFICATION_CODE_TYPE.BINGPHONE
	const flag        = await _checkVerificationCode(phone,type,code)

	const account     = await Account.findOne({where:{uid,status:1}})

	const wechat_key  = account.wechat_key
	const qq_key      = account.qq_key
	const old_phone   = account.phone
	if(old_phone) {
		ctx.body      = CODE.ERROR.ERROR_BIND_PHONE_ALREADY
		return
	}
	if(flag) {
		const res     = await _bindPhone({phone,wechat_key,qq_key})
		ctx.body      = res
		return
	}
	ctx.body          = CODE.ERROR.ERROR_CODE_NOT_CHECK
	
	
}

/**
 * @api {post} /account/loginByPassword 手机号密码登录
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName loginByPassword
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/loginByPassword'
 * @apiParam {String}  phone                 手机号码
 * @apiParam {String}  password              密码
 *
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/loginByPassword
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 * 
 */
export async function loginByPassword(ctx,next) {  
	const phone 	  = ctx.request.body.phone
	const password    = ctx.request.body.password
	if(!password) {
		ctx.body      = CODE.ERROR.ERROR_PASSWORD_NOT_CHECK
		return
	}
	const account       = await Account.findOne({ where : {phone,password,status:1}})

	if(account) {
		ctx.body      = {uid:account.uid,key:UID_KEY.phone}
		if(next) {
			return next()
		}
		return
	}
	ctx.body          = CODE.ERROR.ERROR_PASSWORD_NOT_CHECK
}


/**
 * @api {post} /account/getAccountDetail 获取用户详细信息
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName getAccountDetail
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/getAccountDetail'
 * @apiParam {String}  token                 用户token
 *
 * 
 * @apiSuccess {String}   phone                用户手机
 * @apiSuccess {String}   icon                 用户头像
 * @apiSuccess {String}   nickname             用户昵称
 * 
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/getAccountDetail
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 * 
 */
export async function  getAccountDetail(ctx,next) {
	const token 	   = ctx.body.token
	const uid 	       = token.phone_uid || token.wechat_uid || token.qq_uid
	
	const accountDetail = await AccountDetail.findOne({where : { uid,status:1}}) || {}
	ctx.body            = CODE.success({
		account:{icon:accountDetail.icon,nickname:accountDetail.nickname,phone:accountDetail.phone}
	})
}


/**
 * @api {post} /account/perfectAccountDetail 完善用户详细信息
 * @apiPermission 用户
 * @apiVersion 1.0.0 
 * @apiName perfectAccountDetail
 * @apiGroup account
 * @apiExample 请求示例:
 * curl -H "Content-Type: application/json" -X POST -d '{}' 'http://copyright.hotchain.vip/api/account/perfectAccountDetail'
 * @apiParam {String}  token                 用户token
 * @apiParam {String}  icon                  用户头像
 * @apiParam {String}  nickname              用户昵称
 *
 * 
 * @apiSuccess {String}   phone                用户手机
 * @apiSuccess {String}   icon                 用户头像
 * @apiSuccess {String}   nickname             用户昵称
 * 
 * @apiSampleRequest http://copyright.hotchain.vip/api/account/perfectAccountDetail
 * @apiSuccessExample {json} 成功返回
 *     HTTP/1.1 200 OK
 *     {
    "code": 0
  }
 *
 * @apiUse ERROR
 * 
 */
export async function  perfectAccountDetail(ctx,next) {
	const token 	   = ctx.body.token
	const uid 	       = token.phone_uid || token.wechat_uid || token.qq_uid
	const icon 	       = ctx.request.body.icon
	const nickname 	   = ctx.request.body.nickname

	let accountDetail  = null
	accountDetail      = await AccountDetail.findOne({where:{uid,status:1}})
	const param        = {
		icon , nickname , uid
	}
	accountDetail.icon     = param.icon || accountDetail.icon
	accountDetail.nickname = param.nickname || accountDetail.nickname
	await accountDetail.save()
	ctx.body           = CODE.success({
		account:{icon:accountDetail.icon,nickname:accountDetail.nickname,phone:accountDetail.phone}
	})
}

export async function  checkToken(ctx,next) {
	const token 	  = ctx.request.body.token
	const tokenRes    = await Token.findOne({where:{token,status:1}})
	if(tokenRes) {
		if(tokenRes.ctime + TOKEN_TIME >= getSecond()) {
			ctx.body  = {token:tokenRes}
			if(next) {
				return next()
			}
		}
		ctx.body      = CODE.ERROR.ERROR_TOKEN_LOSE
		return
	}
	ctx.body          = CODE.ERROR.ERROR_TOKEN_NOT_CHECK
}

export async function getAccount(ctx) {
	const uid 	      = ctx.body.uid
	const key         = ctx.body.key
	const account     = await _getAccount(uid,key)
	ctx.body          = CODE.success({account})
}


async function createAccount(ctx,param) {
	const phone       = param.phone
	const password    = param.password
	const key         = param.key
	const wechat_key  = param.wechat_key
	const qq_key      = param.qq_key
	const ctime       = getSecond()
	let account       = null
	let token         = null
	if(key == UID_KEY.phone) {
		account       = await Account.create({phone,password,uid:uuid(),ctime})
		await AccountDetail.create({phone,uid:account.uid})
		token         = await Token.create({phone_uid:account.uid,token:uuid()})
		ctx.body      = CODE.success({token:token.token,phone:phone})	
	} else if(key == UID_KEY.wechat) {
		account       = await Account.create({wechat_key,uid:uuid(),ctime})
		await AccountDetail.create({uid:account.uid})
		token         = await Token.create({wechat_uid:account.uid,token:uuid()})
		ctx.body      = CODE.success({token:token.token})
	} else if(key == UID_KEY.qq) {
		account       = await Account.create({qq_key,uid:uuid(),ctime})
		await AccountDetail.create({uid:account.uid})
		token         = await Token.create({qq_uid:account.uid,token:uuid()})
		ctx.body      = CODE.success({token:token.token})
	}
}


/**
 * @apiDefine ERROR
 * @apiErrorExample {json} 错误返回:
 *     {
 *       "code": "错误码",
 *       "error": "错误描述",
 *       "msg":"错误信息"
 *     }
 */